home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Workbench Add-On
/
Workbench Add-On - Volume 1.iso
/
Dev
/
Oberon
/
source
/
OC
/
OCP.mod
< prev
next >
Wrap
Text File
|
1995-06-29
|
37KB
|
1,110 lines
(*************************************************************************
$RCSfile: OCP.mod $
Description: Code selection for standard procedures
Created by: fjc (Frank Copeland)
$Revision: 5.16 $
$Author: fjc $
$Date: 1995/06/29 19:10:59 $
Copyright © 1990-1993, ETH Zuerich
Copyright © 1993-1995, Frank Copeland
This module forms part of the OC program
See OC.doc for conditions of use and distribution
Log entries are at the end of the file.
*************************************************************************)
<* STANDARD- *> <* MAIN- *> <*$ LongVars+ *>
MODULE OCP;
IMPORT SYS := SYSTEM, OCM, OCS, OCT, OCC, OCI, OCE;
(* --- Local declarations ----------------------------------------------- *)
CONST
(* object modes *)
Var = OCM.Var; VarX = OCM.VarX; Ind = OCM.Ind; IndX = OCM.IndX;
RegI = OCM.RegI; RegX = OCM.RegX; Lab = OCM.Lab; LabI = OCM.LabI;
Con = OCM.Con; Push = OCM.Push; Pop = OCM.Pop; Coc = OCM.Coc;
Reg = OCM.Reg; Fld = OCM.Fld; Typ = OCM.Typ; Abs = OCM.Abs;
XProc = OCM.XProc; LProc = OCM.LProc;
(* System flags *)
OberonFlag = OCM.OberonFlag; M2Flag = OCM.M2Flag; CFlag = OCM.CFlag;
BCPLFlag = OCM.BCPLFlag; AsmFlag = OCM.AsmFlag;
(* structure forms *)
Undef = OCT.Undef; Byte = OCT.Byte; Bool = OCT.Bool; Char = OCT.Char;
SInt = OCT.SInt; Int = OCT.Int; LInt = OCT.LInt; Real = OCT.Real;
LReal = OCT.LReal; Set = OCT.Set; String = OCT.String;
NilTyp = OCT.NilTyp; NoTyp = OCT.NoTyp; Pointer = OCT.Pointer;
ProcTyp = OCT.ProcTyp; Array = OCT.Array; DynArr = OCT.DynArr;
Record = OCT.Record; PtrTyp = OCT.PtrTyp; AdrTyp = OCT.AdrTyp;
BPtrTyp = OCT.BPtrTyp; BSet = OCT.BSet; WSet = OCT.WSet; Word = OCT.Word;
Longword = OCT.Longword; TagTyp = OCT.TagTyp;
intSet = {SInt, Int, LInt};
realSet = {Real, LReal};
setSet = {BSet, WSet, Set};
ptrSet = {Pointer, PtrTyp, AdrTyp, BPtrTyp};
uptrSet = {AdrTyp, BPtrTyp};
allSet = {0 .. 31};
adrSet = {LInt, Pointer, PtrTyp, AdrTyp, Longword};
bitOpSet = intSet + setSet + {Byte, Char, Word, Longword};
putSet =
{Undef .. LInt, Word, Longword, ProcTyp} + setSet + ptrSet + realSet;
(* CPU Registers *)
D0 = 0; D1 = 1; D7 = 7; A0 = 8; A1 = 9; A3 = 11; A4 = 12; A5 = 13;
A6 = 14; A7 = 15; BP = A4; FP = A5; SP = A7;
DataRegs = {D0 .. D7};
AdrRegs = {A0 .. A7};
(* Data sizes *)
B = 1; W = 2; L = 4;
(* --- Procedure declarations ------------------------------------------- *)
(*------------------------------------*)
PROCEDURE CheckCleanupProc (VAR x : OCT.Item);
VAR par : OCT.Object; typ : OCT.Struct;
BEGIN (* CheckCleanupProc *)
IF (x.mode = XProc) OR (x.typ.form = ProcTyp) THEN
IF x.mode = XProc THEN par := x.obj.link; typ := x.typ
ELSE par := x.typ.link; typ := x.typ.BaseTyp;
END;
IF OCT.IsParam (par) THEN OCS.Mark (117) END;
IF typ # OCT.notyp THEN OCS.Mark (301) END
ELSE
OCS.Mark (300)
END
END CheckCleanupProc;
(*----------------------------%-------*)
PROCEDURE NeedsTag (typ : OCT.Struct) : BOOLEAN;
VAR fld : OCT.Object;
BEGIN (* NeedsTag *)
IF (typ.form IN {Pointer, Record}) & (typ.sysflg = OberonFlag) THEN
RETURN TRUE
ELSIF typ.form IN {Array, DynArr} THEN
RETURN NeedsTag (typ.BaseTyp)
END;
RETURN FALSE
END NeedsTag;
(*------------------------------------*)
PROCEDURE SaveRegs * ( fctno : INTEGER; VAR R : OCC.RegState );
VAR x : OCT.Item;
BEGIN (* SaveRegs *)
CASE fctno OF
OCT.pDISPOSE, OCT.pMOVE :
x.mode := Undef; OCC.SaveRegisters (R, x, OCC.AllRegs)
|
ELSE
R.regs := {}
END
END SaveRegs;
(*------------------------------------*)
PROCEDURE StPar1 *
( VAR x : OCT.Item; fctno : INTEGER; VAR R : OCC.RegState );
VAR f, f1 : INTEGER; y, z, r0, r1 : OCT.Item;
size : LONGINT; par : OCT.Object;
typ : OCT.Struct; desc : OCT.Desc; s : SET;
(*------------------------------------*)
PROCEDURE GetTag (VAR x : OCT.Item);
VAR y, z : OCT.Item;
BEGIN (* GetTag *)
IF OCC.InAdrReg (x.obj) THEN
OCC.GetAReg (x, x.obj)
ELSE
y := x; y.obj := NIL; y.typ := OCT.ptrtyp; OCC.GetAReg (x, x.obj);
IF OCS.pragma [OCS.nilChk] THEN
OCC.GetDReg (z, NIL); OCC.Move (L, y, z); (* MOVE.L x,Dn *)
OCC.TrapCC (OCC.NilCheck, OCC.EQ);
OCC.Move (L, z, x); OCI.Unload (z) (* MOVEA.L Dn, An *)
ELSE
OCC.Move (L, y, x); (* MOVEA.L x, An *)
END;
OCI.Unload (y)
END;
x.mode := RegI; x.a1 := -4; x.a2 := 0; x.obj := OCC.wasderef;
x.rdOnly := FALSE;
END GetTag;
BEGIN (* StPar1 *)
f := x.typ.form; size := x.typ.size;
CASE fctno OF
OCT.pABS :
IF f IN intSet THEN
IF x.mode = Con THEN
x.a0 := ABS (x.a0)
ELSE
OCI.Load (x); (* MOVE.z x,Dn *)
OCC.PutF1 (OCC.TST, size, x); (* TST.z Dn *)
OCC.PutWord (6A02H); (* BPL 1$ *)
OCC.PutF1 (OCC.NEG, size, x) (* NEG.z Dn *)
END
ELSIF f IN realSet THEN
OCC.LoadRegParams1 (R, x);
OCC.CallKernel (OCC.kSPAbs);
OCC.RestoreRegisters (R, x)
ELSE
OCS.Mark (111)
END
|
OCT.pCAP :
IF (f = String) & (x.a1 <= 2) THEN
x.a0 := x.a2; x.typ := OCT.chartyp; f := Char
END;
IF f = Char THEN
IF x.mode = Con THEN
x.a0 := ORD (CAP (CHR (x.a0)))
ELSE
y.mode := Con; y.typ := OCT.chartyp;
OCI.Load (x); (* MOVE x,Dn *)
y.a0 := ORD ("a");
OCC.PutF6 (OCC.CMPI, B, y, x); (* CMPI "a", Dn *)
OCC.PutWord (6510H); (* BCS 1$ *)
y.a0 := ORD ("z");
OCC.PutF6 (OCC.CMPI, B, y, x); (* CMPI "z", Dn *)
OCC.PutWord (6306H); (* BLS 0$ *)
y.a0 := 0E0H; OCC.PutF6 (OCC.CMPI, B, y, x); (* CMPI 0E0X,Dn *)
OCC.PutWord (6504H); (* BCS 1$ *)
y.a0 := 0DFH; OCC.PutF6 (OCC.ANDI, B, y, x); (* 0$ ANDI 0DFH,Dn *)
END (* 1$ *)
ELSE
OCS.Mark (111); x.typ := OCT.chartyp
END
|
OCT.pCHR :
IF ~(f IN {Undef, Byte, SInt, Int, LInt}) THEN OCS.Mark (111) END;
IF ~(f IN {Byte, SInt}) & (x.mode # Con) THEN OCI.Load (x) END;
x.typ := OCT.chartyp
|
OCT.pENTIER :
IF f IN realSet THEN
OCC.LoadRegParams1 (R, x);
OCC.CallKernel (OCC.kSPFix);
OCC.RestoreRegisters (R, x)
ELSE OCS.Mark (111)
END;
x.typ := OCT.linttyp;
|
OCT.pHALT :
IF (f IN intSet) & (x.mode = Con) THEN
r0.mode := Reg; r0.a0 := D0;
OCC.Move (L, x, r0); (* MOVE.L x,D0 *)
y.mode := Con; y.a0 := 0; y.typ := OCT.stringtyp;
y.label := OCT.ConstLabel;
OCC.PutF2 (OCC.LEA, y, A0); (* LEA ModuleName,A0 *)
y.a0 := (OCS.line * 10000H) + OCS.col; y.typ := OCT.linttyp;
r1.mode := Reg; r1.a0 := D1;
OCC.Move (L, y, r1); (* MOVE.L pos,D1 *)
OCC.CallKernel (OCC.kHalt) (* JSR Kernel_Halt *)
ELSE
OCS.Mark (17)
END;
x.typ := OCT.notyp
|
OCT.pLONG :
IF (f = String) & (x.a1 <= 2) THEN
x.a0 := x.a2; x.typ := OCT.chartyp; f := Char
END;
IF f = SInt THEN OCE.ConvertInts (x, OCT.inttyp)
ELSIF f = Int THEN OCE.ConvertInts (x, OCT.linttyp)
ELSIF f = BSet THEN
IF OCS.option [OCS.standard] THEN OCS.Mark (915) END;
IF x.mode # Con THEN
y := x; x.mode := Con; x.a0 := 0; x.typ := OCT.wsettyp;
OCI.Load (x); OCC.Move (B, y, x)
END;
x.typ := OCT.wsettyp
ELSIF f = WSet THEN
IF OCS.option [OCS.standard] THEN OCS.Mark (915) END;
IF x.mode # Con THEN
y := x; x.mode := Con; x.a0 := 0; x.typ := OCT.settyp;
OCI.Load (x); OCC.Move (W, y, x)
END;
x.typ := OCT.settyp
ELSIF f = Real THEN
x.typ := OCT.lrltyp
ELSIF f = Char THEN
IF x.mode # Con THEN
y := x; x.mode := Con; x.a0 := 0; x.typ := OCT.linttyp;
OCI.Load (x); OCC.Move (B, y, x)
END;
x.typ := OCT.linttyp
ELSE
OCS.Mark (111)
END
|
OCT.pMAX :
IF x.mode = Typ THEN
x.mode := Con;
CASE f OF
Bool : x.a0 := OCM.MaxBool |
Char : x.a0 := OCM.MaxChar |
SInt : x.a0 := OCM.MaxSInt |
Int : x.a0 := OCM.MaxInt |
LInt : x.a0 := OCM.MaxLInt |
Real : x.a0 := 07F7FFFFFH |
LReal : x.a0 := 07F7FFFFFH |
BSet : x.a0 := OCM.MaxBSet; x.typ := OCT.inttyp |
WSet : x.a0 := OCM.MaxWSet; x.typ := OCT.inttyp |
Set : x.a0 := OCM.MaxSet; x.typ := OCT.inttyp |
ELSE
OCS.Mark (111)
END; (* CASE f *)
ELSE
OCS.Mark (110)
END
|
OCT.pMIN :
IF x.mode = Typ THEN
x.mode := Con;
CASE f OF
Bool : x.a0 := OCM.MinBool |
Char : x.a0 := OCM.MinChar |
SInt : x.a0 := OCM.MinSInt |
Int : x.a0 := OCM.MinInt |
LInt : x.a0 := OCM.MinLInt |
Real : x.a0 := 0FF7FFFFFH |
LReal : x.a0 := 0FF7FFFFFH |
BSet, WSet, Set : x.a0 := OCM.MinSet; x.typ := OCT.inttyp |
ELSE
OCS.Mark (111)
END; (* CASE f *)
ELSE
OCS.Mark (110)
END
|
OCT.pNEW :
IF (f = Pointer) & (x.mode # Con) THEN
IF x.rdOnly THEN OCS.Mark (324) END;
typ := x.typ; f1 := typ.sysflg;
typ := typ.BaseTyp; f := typ.form;
IF f = DynArr THEN
OCI.UnloadDesc (x);
desc := x.desc; IF desc = NIL THEN NEW (desc) END;
desc.lev := x.lev; desc.mode := x.mode; desc.a0 := x.a0;
desc.a1 := x.a1; desc.a2 := x.a2; x.desc := desc;
END;
z.mode := Undef; OCC.SaveRegisters (R, z, OCC.AllRegs);
IF (f = DynArr) & (x.mode IN {VarX, IndX, RegI, RegX}) THEN
IF x.mode IN {RegI, RegX} THEN OCC.ReserveReg (x.a0, NIL) END;
IF x.mode # RegI THEN OCC.ReserveReg (x.a2, NIL) END
END;
z.mode := Push; z.a0 := SP;
IF (f1 = OberonFlag) & NeedsTag (typ) THEN
IF f = DynArr THEN
WHILE typ.form = DynArr DO typ := typ.BaseTyp END;
WHILE typ.form = Array DO typ := typ.BaseTyp END;
ELSIF f = Array THEN
WHILE typ.form = Array DO typ := typ.BaseTyp END;
END;
y.mode := Con; y.a0 := 0; y.typ := OCT.tagtyp;
y.label := typ.label;
OCC.PutF3 (OCC.PEA, y); (* PEA #tag *)
IF f = Array THEN
y.mode := Con; y.a0 := typ.size; y.typ := OCT.linttyp;
OCC.Move (L, y, z); (* MOVE.L #size,-(A7) *)
END
ELSIF f # DynArr THEN
y.mode := Con; y.a0 := typ.size; y.typ := OCT.linttyp;
OCC.Move (L, y, z); (* MOVE.L #size, -(A7) *)
END
ELSE OCS.Mark (111)
END
|
OCT.pODD :
IF f IN intSet THEN
y.mode := Con; y.a0 := 0; y.typ := OCT.inttyp;
IF f = SInt THEN OCC.Bit (OCC.BTST, y, x);
ELSE OCI.Load (x); OCC.Bit (OCC.BTST, y, x); OCI.Unload (x)
END;
ELSE
OCS.Mark (111)
END;
OCE.setCC (x, OCC.NE)
|
OCT.pORD :
IF (f = String) & (x.a1 <= 2) THEN
x.a0 := x.a2; x.typ := OCT.chartyp; f := Char
END;
IF (f = Char) OR (f = Byte) THEN
IF x.mode # Con THEN
y := x; x.mode := Con; x.a0 := 0; x.typ := OCT.inttyp;
OCI.Load (x); OCC.Move (B, y, x)
END
ELSE
OCS.Mark (111)
END;
x.typ := OCT.inttyp
|
OCT.pSHORT :
IF f = LInt THEN
IF x.mode = Con THEN
OCE.SetIntType (x); IF x.typ.form = LInt THEN OCS.Mark (203) END
ELSE
OCI.Load (x);
IF OCS.pragma [OCS.rangeChk] THEN
OCC.GetDReg (y, NIL); OCC.Move (W, x, y); OCI.EXT (L, y.a0);
OCI.CMP (L, x, y); OCC.TrapCC (OCC.RangeCheck, OCC.NE);
END
END;
x.typ := OCT.inttyp
ELSIF f = Int THEN
IF x.mode = Con THEN
OCE.SetIntType (x); IF x.typ.form # SInt THEN OCS.Mark (203) END
ELSE
OCI.Load (x);
IF OCS.pragma [OCS.rangeChk] THEN
OCC.GetDReg (y, NIL); OCC.Move (B, x, y); OCI.EXT (W, y.a0);
OCI.CMP (W, x, y); OCC.TrapCC (OCC.RangeCheck, OCC.NE);
END
END;
x.typ := OCT.sinttyp
ELSIF f = Set THEN
IF OCS.option [OCS.standard] THEN OCS.Mark (915) END;
IF x.mode = Con THEN
s := SYS.VAL (SET, x.a0);
IF (s - {0..15}) # {} THEN OCS.Mark (203) END;
ELSE
OCI.Load (x);
IF OCS.pragma [OCS.rangeChk] THEN
y.mode := Con; y.a0 := 0; y.typ := OCT.linttyp;
OCI.Load (y); OCC.Move (W, x, y);
OCI.CMP (L, x, y); OCC.TrapCC (OCC.RangeCheck, OCC.NE);
END
END;
x.typ := OCT.wsettyp
ELSIF f = WSet THEN
IF OCS.option [OCS.standard] THEN OCS.Mark (915) END;
IF x.mode = Con THEN
s := SYS.VAL (SET, x.a0);
IF (s - {0..7}) # {} THEN OCS.Mark (203) END;
ELSE
OCI.Load (x);
IF OCS.pragma [OCS.rangeChk] THEN
y.mode := Con; y.a0 := 0; y.typ := OCT.linttyp;
OCI.Load (y); OCC.Move (B, x, y);
OCI.CMP (W, x, y); OCC.TrapCC (OCC.RangeCheck, OCC.NE)
END
END;
x.typ := OCT.bsettyp
ELSIF f = LReal THEN
x.typ := OCT.realtyp
ELSE
OCS.Mark (111)
END
|
OCT.pADR :
OCI.Adr (x); x.typ := OCT.adrtyp
|
OCT.pCC :
IF (f = SInt) & (x.mode = Con) THEN
IF (x.a0 >= 0) & (x.a0 < 16) THEN OCE.setCC (x, x.a0)
ELSE OCS.Mark (219)
END
ELSE OCS.Mark (17)
END
|
OCT.pDISPOSE :
IF f IN ptrSet THEN
IF x.rdOnly THEN OCS.Mark (324) END;
IF x.typ.sysflg = BCPLFlag THEN
y := x; OCI.Load (y);
OCC.PutF5 (OCC.ADD, L, y, y); (* ADD.L Dm, Dm *)
OCC.PutF5 (OCC.ADD, L, y, y); (* ADD.L Dm, Dm *)
OCC.Move (L, y, x); OCI.Unload (y)
END;
y.mode := Push; y.a0 := SP;
OCC.ForgetObj (x.obj);
IF x.mode IN {Ind, IndX} THEN OCI.MoveAdr (x, y)
ELSE OCC.PutF3 (OCC.PEA, x)
END;
OCI.Unload (x);
OCC.CallKernel (OCC.kDispose);
z.mode := Undef; OCC.ForgetRegs; OCC.RestoreRegisters (R, z)
ELSE
OCS.Mark (111)
END;
x.typ := OCT.notyp
|
OCT.pSIZE :
IF x.mode = Typ THEN x.a0 := x.typ.size
ELSE OCS.Mark (110); x.a0 := 1
END;
x.mode := Con; OCE.SetIntType (x)
|
OCT.pSTRLEN :
IF ((f = Array) OR (f = DynArr)) & (x.typ.BaseTyp.form = Char) THEN
y := x; OCI.LoadAdr (y); y.mode := Pop; (* LEA <y>,Ay *)
OCC.ForgetReg (y.a0);
x.mode := Con; x.a0 := 0; x.typ := OCT.linttyp;
OCI.Load (x); (* MOVEQ #0,Dx *)
OCC.PutF1 (OCC.TST, B, y); OCC.FreeReg (y); (* 1$ TST.B (Ay)+ *)
OCC.PutWord (6704H); (* BEQ 2$ *)
OCC.PutF7 (OCC.ADDQ, L, 1, x); (* ADDQ.L #1,Dx *)
OCC.PutWord (60F8H); (* BRA 1$ *)
ELSIF f = String THEN (* 2$ *)
x.mode := Con; x.a0 := x.a1 - 1; x.typ := OCT.linttyp
ELSE
OCS.Mark (111)
END
|
OCT.pASH :
IF f IN intSet THEN
OCI.Load (x); IF f # LInt THEN OCE.ConvertInts (x, OCT.linttyp) END
ELSE
OCS.Mark (111)
END
|
OCT.pASSERT :
IF f = Bool THEN
IF x.mode = Con THEN
IF x.a0 = 0 THEN OCS.Mark (319) ELSE OCS.Mark (320) END;
OCE.setCC (x, OCC.T)
END;
ELSE OCS.Mark (120)
END
|
OCT.pCOPY :
IF
~((((f = Array) OR (f = DynArr)) & (x.typ.BaseTyp.form = Char))
OR (f = String))
THEN
OCS.Mark (111)
END
|
OCT.pDEC, OCT.pINC :
IF x.mode >= Con THEN OCS.Mark (112)
ELSIF ~(f IN intSet) THEN OCS.Mark (111)
ELSIF x.rdOnly THEN OCS.Mark (324)
END
|
OCT.pINCL, OCT.pEXCL :
IF x.mode >= Con THEN OCS.Mark (112)
ELSIF ~(f IN setSet) THEN OCS.Mark (111); x.typ := OCT.settyp
ELSIF x.rdOnly THEN OCS.Mark (324)
END
|
OCT.pLEN :
IF (f # DynArr) & (f # Array) THEN OCS.Mark (131) END
|
OCT.pAND, OCT.pOR, OCT.pXOR :
IF ~(f IN bitOpSet) THEN OCS.Mark (111) END
|
OCT.pBIT, OCT.pGET, OCT.pPUT :
IF (f IN intSet) & (x.mode = Con) THEN
x.mode := Abs; x.obj := NIL
ELSIF f IN adrSet THEN
IF x.mode = Var THEN
x.mode := Ind; x.a1 := 0
ELSE
OCC.GetAReg (y, NIL); x.obj := NIL; OCC.Move (L, x, y);
x := y; x.mode := RegI; x.a1 := 0
END
ELSE
OCS.Mark (111)
END
|
OCT.pGETREG, OCT.pPUTREG, OCT.pREG :
IF (f IN intSet) & (x.mode = Con) THEN
IF (0 <= x.a0) & (x.a0 <= 15) THEN
x.mode := Reg;
IF fctno = OCT.pREG THEN
OCC.ReserveReg (x.a0, NIL); x.typ := OCT.lwordtyp
END
ELSE OCS.Mark (219)
END
ELSE
OCS.Mark (17)
END
|
OCT.pLSH, OCT.pROT :
IF (f = String) & (x.a1 <= 2) THEN
x.a0 := x.a2; x.typ := OCT.chartyp; f := Char
END;
IF f IN bitOpSet THEN OCI.Load (x)
ELSE OCS.Mark (111)
END
|
OCT.pSYSNEW :
IF ~(f IN ptrSet) OR (x.mode = Con) THEN OCS.Mark (111)
ELSIF x.rdOnly THEN OCS.Mark (324)
ELSIF NeedsTag (x.typ) THEN OCS.Mark (339)
ELSE y.mode := Undef; OCC.SaveRegisters (R, y, OCC.AllRegs)
END
|
OCT.pVAL : IF x.mode # Typ THEN OCS.Mark (110) END
|
OCT.pMOVE :
IF (f IN adrSet) THEN
y.mode := Push; y.a0 := SP;
OCC.Move (L, x, y); OCI.Unload (x);
ELSE
OCS.Mark (111)
END
|
OCT.pTAG :
typ := x.typ; f1 := typ.sysflg;
IF f = Pointer THEN typ := typ.BaseTyp END;
IF (typ.form = Record) & (f1 = OberonFlag) THEN
IF x.mode = Typ THEN (* Type *)
x.mode := Con; x.a0 := 0; x.a1 := 0; x.typ := OCT.tagtyp;
x.label := typ.label;
OCI.Adr (x)
ELSIF (x.mode <= RegX) & (f = Pointer) THEN (* Pointer variable *)
GetTag (x)
ELSIF (x.mode = Ind) & (x.obj # NIL) & (x.obj # OCC.wasderef) THEN
(* VAR parameter *)
x.mode := Var; x.obj := NIL; INC (x.a0, 4)
ELSE (* Bzzzzt! *)
OCS.Mark (338)
END
ELSIF f = PtrTyp THEN
IF (x.mode <= RegX) THEN (* Pointer variable *)
GetTag (x)
ELSE (* Bzzzzt! *)
OCS.Mark (338)
END
ELSE
OCS.Mark (338)
END;
x.typ := OCT.tagtyp; x.rdOnly := FALSE
|
ELSE
OCS.Mark (1014); OCS.Mark (fctno)
END; (* CASE fctno *)
END StPar1;
(*------------------------------------*)
PROCEDURE StPar2 *
( VAR par1, par2 : OCT.Item; fctno : INTEGER; VAR R : OCC.RegState );
VAR f, dim : INTEGER; L0, L1, op : LONGINT; typ, btyp, t1 : OCT.Struct;
freePar2 : BOOLEAN; x, y, r0, r1 : OCT.Item;
dsc : OCT.Desc;
BEGIN (* StPar2 *)
f := par2.typ.form; freePar2 := FALSE;
IF fctno < OCT.TwoPar THEN OCS.Mark (64); RETURN END;
CASE fctno OF
OCT.pASH, OCT.pLSH, OCT.pROT :
IF
((fctno = OCT.pASH) & (f IN intSet)) OR
((fctno # OCT.pASH) & (f IN bitOpSet))
THEN
IF (par2.mode = Con) & (par2.a0 = 0) THEN RETURN END;
IF fctno = OCT.pASH THEN op := OCC.ASR
ELSIF fctno = OCT.pLSH THEN op := OCC.LSR
ELSE op := OCC.ROR
END;
IF par2.mode = Con THEN
IF par2.a0 < 0 THEN par2.a0 := -par2.a0 ELSE INC (op, 100H) END;
IF par2.a0 > 8 THEN OCI.Load (par2); freePar2 := TRUE END;
OCC.Shift (op, par1.typ.size, par2, par1);
IF freePar2 THEN OCC.FreeReg (par2) END
ELSE
OCI.Load (par2); (* MOVE.L <par2>,Dn *)
OCC.PutF1 (OCC.TST, par2.typ.size, par2);(* TST.? Dn *)
L0 := OCC.pc; OCC.PutWord (6A00H); (* BPL.S 1$ *)
OCC.PutF1 (OCC.NEG, par2.typ.size, par2);(* NEG.? Dn *)
OCC.Shift (op, par1.typ.size, par2, par1);
(* opR.? Dn,<par1> *)
L1 := OCC.pc; OCC.PutWord (6000H); (* BRA.S $2 *)
OCC.PatchWord (L0, OCC.pc - L0 - 2);
OCC.Shift (op+100H, par1.typ.size, par2, par1);
(* 1$ opL.? Dn,<par1> *)
OCC.PatchWord (L1, OCC.pc - L1 - 2); (* 2$ *)
END
ELSE
OCS.Mark (111)
END
|
OCT.pASSERT :
IF (par2.mode = Con) & (f IN intSet) THEN
IF par1.mode # Coc THEN
OCC.PutF1 (OCC.TST, B, par1); (* TST.B <par1> *)
OCI.Unload (par1); L0 := OCC.pc;
OCC.PutWord (OCC.BNE) (* BNE.S 2$ *)
ELSE
op := OCC.Bcc + (par1.a0 * 100H);
OCC.PutWord (op);
OCC.PutWord (par1.a1); (* Bcc 2$ *)
L0 := OCC.pc - 2; OCC.FixLink (par1.a2);
END;
r0.mode := Reg; r0.a0 := D0;
OCC.Move (L, par2, r0); (* 1$ MOVE.L #par2,D0 *)
OCI.Unload (par2);
x.mode := Con; x.a0 := 0; x.typ := OCT.stringtyp;
x.label := OCT.ConstLabel;
OCC.PutF2 (OCC.LEA, x, A0); (* LEA ModuleName,A0 *)
x.a0 := (OCS.line * 10000H) + OCS.col; x.typ := OCT.linttyp;
r1.mode := Reg; r1.a0 := D1;
OCC.Move (L, x, r1); (* MOVE.L pos,D1 *)
OCC.CallKernel (OCC.kHalt); (* JSR Kernel.Halt *)
OCC.ForgetRegs;
IF par1.mode # Coc THEN (* 2$ *)
OCC.PatchWord (L0, OCC.pc - L0 - 2)
ELSE OCC.FixLink (L0)
END;
ELSE OCS.Mark (17)
END;
par1.typ := OCT.notyp
|
OCT.pDEC, OCT.pINC :
IF par1.typ # par2.typ THEN
IF (par1.typ.form = Int) & (f = SInt) THEN
OCE.ConvertInts (par2, OCT.inttyp)
ELSIF (par1.typ.form = LInt) & (f IN {SInt, Int}) THEN
OCE.ConvertInts (par2, OCT.linttyp)
ELSE OCS.Mark (111)
END
ELSIF par2.mode # Con THEN
OCI.Load (par2)
END;
IF fctno = OCT.pDEC THEN op := OCC.SUB ELSE op := OCC.ADD END;
OCC.PutF5 (op, par1.typ.size, par2, par1);
IF OCS.pragma [OCS.ovflChk] THEN OCC.Trap (OCC.OverflowCheck) END;
par1.typ := OCT.notyp
|
OCT.pEXCL :
OCE.Set0 (x, par2);
IF x.mode = Con THEN
x.a0 := SYS.VAL (LONGINT, allSet - SYS.VAL (SET, x.a0));
OCC.PutF6 (OCC.ANDI, par1.typ.size, x, par1)
ELSE
OCC.PutF1 (OCC.NOT, L, x);
OCC.PutF5 (OCC.AND, par1.typ.size, x, par1)
END;
par1.typ := OCT.notyp
|
OCT.pINCL :
OCE.Set0 (x, par2);
IF x.mode = Con THEN OCC.PutF6 (OCC.ORI, par1.typ.size, x, par1)
ELSE OCC.PutF5 (OCC.iOR, par1.typ.size, x, par1)
END;
par1.typ := OCT.notyp
|
OCT.pLEN :
IF (par2.mode = Con) & (f = SInt) THEN
dim := SHORT (par2.a0); typ := par1.typ;
WHILE (dim > 0) & (typ.form IN {DynArr, Array}) DO
typ := typ.BaseTyp; DEC (dim)
END;
IF (dim # 0) OR ~(typ.form IN {DynArr, Array}) THEN OCS.Mark (132)
ELSE
IF typ.form = DynArr THEN OCI.DescItem (par1, par1.desc, typ.adr)
ELSE par1.mode := Con; par1.a0 := typ.n
END;
par1.typ := OCT.linttyp
END
ELSE
OCS.Mark (111)
END
|
OCT.pAND, OCT.pOR, OCT.pXOR :
IF f IN bitOpSet THEN
IF (par1.mode = Con) & (par2.mode = Con) THEN
IF fctno = OCT.pAND THEN
par1.a0 := SYS.AND (par1.a0, par2.a0)
ELSIF fctno = OCT.pXOR THEN
par1.a0 := SYS.XOR (par1.a0, par2.a0)
ELSE
par1.a0 := SYS.LOR (par1.a0, par2.a0)
END;
IF f IN intSet THEN OCE.SetIntType (par1) END
ELSE
IF fctno = OCT.pAND THEN op := OCC.AND
ELSIF fctno = OCT.pXOR THEN op := OCC.EOR
ELSE op := OCC.iOR
END;
IF par1.mode = Con THEN
IF par1.typ.form # par2.typ.form THEN par1.typ := par2.typ END;
OCI.Load (par2); OCC.PutF5 (op, par2.typ.size, par1, par2);
par1 := par2
ELSIF par2.mode = Con THEN
IF par2.typ.form # par1.typ.form THEN par2.typ := par1.typ END;
OCI.Load (par1); OCC.PutF5 (op, par1.typ.size, par2, par1)
ELSE
IF par1.typ.form = par2.typ.form THEN
OCI.Load (par1); IF op = OCC.EOR THEN OCI.Load (par2) END;
OCC.PutF5 (op, par1.typ.size, par2, par1); OCI.Unload (par2)
ELSE
OCS.Mark (100)
END
END
END
ELSE
OCS.Mark (111)
END
|
OCT.pBIT :
IF f IN intSet THEN
IF (par2.mode = Con) & (par2.a0 >= 8) THEN OCI.Load (par1)
ELSIF (par2.mode # Con) THEN OCI.Load (par1); OCI.Load (par2)
END;
OCC.Bit (OCC.BTST, par2, par1); OCI.Unload (par1); OCI.Unload (par2)
ELSE
OCS.Mark (111)
END;
OCE.setCC (par1, OCC.NE)
|
OCT.pGET, OCT.pGETREG :
IF par2.mode >= Con THEN OCS.Mark (112)
ELSIF ~(f IN realSet) THEN
IF par2.rdOnly THEN OCS.Mark (324) END;
OCC.Move (par2.typ.size, par1, par2);
OCC.ForgetObj (par2.obj)
ELSE OCS.Mark (111)
END;
par1.typ := OCT.notyp
|
OCT.pPUT, OCT.pPUTREG :
IF par2.mode IN {XProc, LProc} THEN OCI.MoveAdr (par2, par1)
ELSIF f IN putSet THEN OCC.Move (par2.typ.size, par2, par1)
ELSE OCS.Mark (111)
END;
par1.typ := OCT.notyp
|
OCT.pSYSNEW :
x.mode := Push; x.a0 := SP;
IF par2.typ.form # LInt THEN OCE.ConvertInts (par2, OCT.linttyp) END;
OCC.Move (L, par2, x); OCI.Unload (par2)
|
OCT.pVAL : par2.typ := par1.typ; par1 := par2
|
OCT.pCOPY :
IF
((f = Array) OR (f = DynArr)) & (par2.typ.BaseTyp.form = Char)
THEN
IF par2.rdOnly THEN OCS.Mark (324) END;
IF f = Array THEN
x.mode := Con; x.a0 := par2.typ.n;
IF (par1.typ.form = String) & (par1.a1 < x.a0) THEN
x.a0 := par1.a1
ELSIF (par1.typ.form = Array) & (par1.typ.n < x.a0) THEN
x.a0 := par1.typ.n
END;
DEC (x.a0); OCE.SetIntType (x)
ELSE
IF (par1.typ.form = String) & (par1.a1 = 1) THEN
x.mode := Con; x.a0 := 0; x.typ := OCT.sinttyp
ELSE OCI.DescItem (x, par2.desc, par2.typ.adr)
END
END;
OCI.CopyString (par1, par2, x)
ELSE
OCS.Mark (111)
END;
par1.typ := OCT.notyp
|
OCT.pMOVE :
IF (f IN adrSet) THEN
x.mode := Push; x.a0 := SP;
OCC.Move (L, par2, x); OCI.Unload (par2)
ELSE
OCS.Mark (111)
END
|
ELSE
OCS.Mark (1015); OCS.Mark (fctno)
END; (* CASE fctno *)
END StPar2;
(*------------------------------------*)
PROCEDURE StPar3 *
( VAR p, x : OCT.Item; fctno : INTEGER; VAR R : OCC.RegState );
VAR f : INTEGER; y : OCT.Item;
BEGIN (* StPar3 *)
f := x.typ.form;
IF fctno = OCT.pMOVE THEN
IF f IN intSet THEN
IF f # LInt THEN OCE.ConvertInts (x, OCT.linttyp) END;
y.mode := Push; y.a0 := SP;
OCC.Move (L, x, y); OCI.Unload (x);
OCC.CallKernel (OCC.kMove); OCC.ForgetRegs;
y.mode := Undef; OCC.RestoreRegisters (R, y)
ELSE
OCS.Mark (111)
END;
p.typ := OCT.notyp
ELSE
OCS.Mark (64)
END
END StPar3;
(*------------------------------------*)
PROCEDURE StFct *
( VAR p : OCT.Item; fctno, parno : INTEGER; VAR R : OCC.RegState );
VAR
p2, r0, r1, x, y : OCT.Item; L0 : LONGINT; f, f1, proc : INTEGER;
btyp : OCT.Struct;
BEGIN (* StFct *)
IF fctno >= OCT.TwoPar THEN
IF (fctno = OCT.pASSERT) & (parno = 1) THEN
IF p.mode # Coc THEN
OCC.PutF1 (OCC.TST, B, p); (* TST.B <p> *)
OCI.Unload (p); L0 := OCC.pc;
OCC.PutWord (OCC.BNE) (* BNE.S 2$ *)
ELSE
OCC.PutWord (OCC.Bcc + (p.a0 * 100H));
OCC.PutWord (p.a1); (* Bcc 2$ *)
L0 := OCC.pc - 2; OCC.FixLink (p.a2);
END;
p2.mode := Con; p2.a0 := 20; p2.typ := OCT.linttyp;
r0.mode := Reg; r0.a0 := D0;
OCC.Move (L, p2, r0); OCI.Unload (p2); (* 1$ MOVE.L #20,D0 *)
x.mode := Con; x.a0 := 0; x.typ := OCT.stringtyp;
x.label := OCT.ConstLabel;
OCC.PutF2 (OCC.LEA, x, A0); (* LEA ModuleName,A0 *)
x.a0 := (OCS.line * 10000H) + OCS.col; x.typ := OCT.linttyp;
r1.mode := Reg; r1.a0 := D1;
OCC.Move (L, x, r1); (* MOVE.L pos,D1 *)
OCC.CallKernel (OCC.kHalt); (* JSR Kernel.Halt *)
OCC.ForgetRegs;
IF p.mode # Coc THEN (* 2$ *)
OCC.PatchWord (L0, OCC.pc - L0 - 2)
ELSE OCC.FixLink (L0)
END;
p.typ := OCT.notyp
ELSIF (fctno = OCT.pDEC) & (parno = 1) THEN
IF p.rdOnly THEN OCS.Mark (324) END;
p2.mode := Con; p2.a0 := 1; p2.typ := p.typ;
OCC.PutF5 (OCC.SUB, p.typ.size, p2, p);
IF OCS.pragma [OCS.ovflChk] THEN OCC.Trap (OCC.OverflowCheck) END;
p.typ := OCT.notyp
ELSIF (fctno = OCT.pINC) & (parno = 1) THEN
IF p.rdOnly THEN OCS.Mark (324) END;
p2.mode := Con; p2.a0 := 1; p2.typ := p.typ;
OCC.PutF5 (OCC.ADD, p.typ.size, p2, p);
IF OCS.pragma [OCS.ovflChk] THEN OCC.Trap (OCC.OverflowCheck) END;
p.typ := OCT.notyp
ELSIF (fctno = OCT.pLEN) & (parno = 1) THEN
IF p.typ.form = DynArr THEN OCI.DescItem (p, p.desc, p.typ.adr)
ELSE p.mode := Con; p.a0 := p.typ.n; p.typ := OCT.linttyp
END
ELSIF fctno = OCT.pINLINE THEN
p.typ := OCT.notyp
ELSIF fctno = OCT.pSYSNEW THEN
IF
((p.typ.form = Pointer) & (p.typ.sysflg = OberonFlag))
OR (p.typ.form = PtrTyp)
THEN
OCC.PutWord (50E7H) (* ST -(A7) *)
ELSE
OCC.PutWord (51E7H) (* SF -(A7) *)
END;
OCC.CallKernel (OCC.kNewSysBlk); (* JSR NewSysBlk *)
IF p.typ.sysflg = BCPLFlag THEN
OCC.PutWord (0E480H) (* ASR.L #2,D0 *)
END;
x.mode := Undef; OCC.ForgetRegs; OCC.RestoreRegisters (R, x);
r0.mode := Reg; r0.a0 := D0;
OCC.Move (L, r0, p); (* MOVE.L D0,<var> *)
OCC.ForgetObj (p.obj); p.typ := OCT.notyp
ELSIF (parno < 2) OR (fctno = OCT.pMOVE) & (parno < 3) THEN
OCS.Mark (65)
END
ELSIF (fctno = OCT.pNEW) & (parno >= 1) THEN
f := p.typ.form;
IF f = Pointer THEN
f1 := p.typ.sysflg; btyp := p.typ.BaseTyp; f := btyp.form;
r0.mode := Reg; r0.a0 := D0;
IF (f1 = OberonFlag) & NeedsTag (btyp) THEN
IF f = Record THEN
IF parno > 1 THEN OCS.Mark (64) END;
proc := OCC.kNewRecord
ELSIF f = Array THEN
IF parno > 1 THEN OCS.Mark (64) END;
proc := OCC.kNewArray
ELSIF f = DynArr THEN
WHILE btyp.form = DynArr DO btyp := btyp.BaseTyp; DEC (parno) END;
WHILE btyp.form = Array DO btyp := btyp.BaseTyp END;
IF parno > 1 THEN OCS.Mark (64)
ELSIF parno < 1 THEN OCS.Mark (65)
END;
proc := OCC.kNewArray
END
ELSE
IF f1 = OberonFlag THEN
IF f = DynArr THEN
WHILE btyp.form = DynArr DO
btyp := btyp.BaseTyp; DEC (parno)
END;
IF parno > 1 THEN OCS.Mark (64)
ELSIF parno < 1 THEN OCS.Mark (65)
END
END;
OCC.PutWord (50E7H) (* ST -(A7) *)
ELSE
OCC.PutWord (51E7H) (* SF -(A7) *)
END;
proc := OCC.kNewSysBlk
END;
OCC.CallKernel (proc);
IF f1 = BCPLFlag THEN OCC.PutWord (0E480H) END;(* ASR.L #2,D0 *)
x.mode := Undef; OCC.ForgetRegs; OCC.RestoreRegisters (R, x);
OCC.Move (L, r0, p); (* MOVE.L D0,<var> *)
OCC.ForgetObj (p.obj)
END;
p.typ := OCT.notyp
ELSIF parno < 1 THEN
OCS.Mark (65)
END
END StFct;
(*------------------------------------*)
PROCEDURE Inline * (VAR x : OCT.Item);
VAR f : INTEGER;
BEGIN (* Inline *)
f := x.typ.form;
IF (f IN intSet) & (x.mode = Con) THEN
IF f = LInt THEN OCC.PutLong (x.a0)
ELSE OCC.PutWord (x.a0)
END
ELSE
OCS.Mark (17)
END
END Inline;
(*------------------------------------*)
PROCEDURE NewPar * (VAR x, p0, p1 : OCT.Item; n : INTEGER);
VAR f, i : INTEGER; btyp : OCT.Struct; desc, r0, y : OCT.Item;
calcSize : BOOLEAN;
BEGIN (* NewPar *)
IF p1.typ.form IN intSet THEN
f := x.typ.form;
IF (f = Pointer) & (x.typ.sysflg = OberonFlag) THEN
btyp := x.typ; i := 0;
WHILE (btyp.BaseTyp # NIL) & (i < n) DO
btyp := btyp.BaseTyp; INC (i)
END;
f := btyp.form;
IF f = DynArr THEN
IF p1.typ.form # LInt THEN OCE.ConvertInts (p1, OCT.linttyp) END;
OCI.DescItem (desc, x.desc, btyp.adr);
OCC.Move (L, p1, desc);
OCI.UpdateDesc (desc, btyp.adr);
btyp := btyp.BaseTyp; f := btyp.form;
IF p1.mode = Con THEN
IF f # DynArr THEN p1.a0 := p1.a0 * btyp.size END;
calcSize := FALSE
ELSE
calcSize := TRUE
END;
IF n = 1 THEN p0 := p1
ELSE OCE.Op (OCS.times, p0, p1, TRUE)
END;
IF calcSize & (f # DynArr) & (btyp.size > 1) THEN
y.mode := Con; y.a0 := btyp.size; y.typ := OCT.linttyp;
OCE.Op (OCS.times, p0, y, TRUE)
END;
IF f # DynArr THEN
OCI.UnloadDesc (x);
y.mode := Push; y.a0 := SP;
OCC.Move (L, p0, y); OCI.Unload (p0)
END;
ELSE OCS.Mark (64)
END
ELSE OCS.Mark (64)
END
ELSE OCS.Mark (328)
END
END NewPar;
END OCP.
(***************************************************************************
$Log: OCP.mod $
Revision 5.16 1995/06/29 19:10:59 fjc
- Removed code that was second-guessing the garbage collector
Revision 5.15 1995/06/02 18:41:18 fjc
- Various changes to implement the SMALLDATA and RESIDENT
options.
- Now uses OCI.CMP.
Revision 5.14 1995/05/13 23:08:42 fjc
- Changed INTEGER to LONGINT where necessary.
Revision 5.13 1995/05/08 17:07:09 fjc
- OCI.IsParam() --> OCT.IsParam().
Revision 5.11 1995/03/09 19:10:56 fjc
- Incorporated changes from 5.22.
Revision 5.10 1995/02/27 17:05:20 fjc
- Removed tracing code.
- Changed to use new register handling procedures.
Revision 5.9.1.1 1995/03/08 19:20:29 fjc
- OC 5.22
Revision 5.9 1995/01/26 00:17:17 fjc
- Release 1.5
Revision 5.8 1995/01/03 21:22:07 fjc
- Changed OCG to OCM.
Revision 5.7 1994/12/16 17:33:01 fjc
- Changed Symbol to Label.
Revision 5.6 1994/11/13 11:31:33 fjc
- Changed handling of ENTIER.
- [bug] ABS now implemented for reals.
- Implemented SYSTEM.CC.
Revision 5.5 1994/10/23 16:16:31 fjc
- Complete overhaul:
- Added SaveRegs().
- Removed code for handling obsolete SYSTEM procedures:
GC, RC, ARGLEN, ARGS, SIZETAG, SETCLEANUP, BIND,
GETNAME and NEWTAG.
- All access to RTS is now through OCC.CallKernel().
Revision 5.4 1994/09/25 18:01:55 fjc
- Changed to reflect new object modes and system flags.
Revision 5.3 1994/09/15 10:36:36 fjc
- Replaced switches with pragmas.
Revision 5.2 1994/09/08 10:50:49 fjc
- Changed to use pragmas/options.
Revision 5.1 1994/09/03 19:29:08 fjc
- Bumped version number
***************************************************************************)